/*
 * @Author: 飞越疯人院 353362604@qq.com
 * @Date: 2022-06-17 16:02:32
 * @LastEditors: 飞越疯人院 353362604@qq.com
 * @LastEditTime: 2023-01-06 15:00:33
 * @FilePath: \adminstration\src\Pages\Admin\Form.jsx
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

// !!! 准备废弃

import dayjs from 'dayjs'
import { Http } from '../Api'
import { ICON } from '../Configure/Icon'
import { API_LIST } from '../Api/Api'
import { useCallback, useEffect, useState } from 'react'
import { useBoolean, useRequest, useReactive } from 'ahooks'
import { PlusOutlined } from '@ant-design/icons'
import { SeeEnclosureModal } from '../Modal/Modal'
import { MenuBoxList } from '../Router/MenuBoxList'
import { ThrModalList } from '../Modal/ThrModal'
import { UploadFileType, UploadFileMapping } from '../Configure/CommonParameter'
import { Button, Form, Input, InputNumber, message, Select, Spin, TreeSelect, DatePicker, Upload, Cascader } from 'antd'

const { TextArea } = Input
const { THREE } = window

// 时间格式转换
const TimeFormatConversion = (data, { picker, showTime, showDate }, type) => {
    // TODO type 0 -> toString  1 -> toTime
    if (data) data = dayjs(`${data}`)
    else data = dayjs()
    let format = []
    switch (picker) {
        case 'year':
            format[0] = 'YYYY'
            break
        case 'month':
            if (showDate) format[0] = 'YYYY-MM-DD'
            else format[0] = 'YYYY-MM'
            break
        default:
            format[0] = 'YYYY-MM-DD'
            break
    }
    if (showTime) format[1] = 'HH:mm:ss'
    if (type === 0) return dayjs(data, format.join(' '))
    if (type === 1) return dayjs(data).format(format.join(' '))
}

// 平级转树形
const cloneTree = (score, parent = 0) => {
    let tree = []
    score.forEach(item => {
        if (item.parent === parent) {
            item.children = cloneTree(score, item.id)
            tree = [...tree, item]
        }
    })
    return tree
}

export const FormAssembly = ({ url, data, Off, actionRef, AddTo, type, thrData, uuid, RefreshEvent, PPPEvent }) => {
    const { runAsync } = useRequest(Http, { manual: true })
    const [loading, { setTrue, setFalse }] = useBoolean(true)
    const [AddAPI, setAddAPI] = useState()
    const [PutAPI, setPutAPI] = useState()
    const [PageData, setPageData] = useState()
    const [form] = Form.useForm()
    // 菜单是否有icon
    const [MenuIconState, { setTrue: IconTrue, setFalse: IconFalse }] = useBoolean(false)
    // 处理渲染数据
    const RenderingForProcessing = useCallback(
        res => {
            if (AddTo) form.setFieldsValue({ [AddTo.key]: AddTo.uuid })
            if (!data && res?.initialValues) form.setFieldsValue(res.initialValues)
            if (res?.columns) {
                let columns = res.columns.filter(v => !v.hideInModify)
                if (data) {
                    let initial = JSON.parse(JSON.stringify(data))
                    // 判断数据类型
                    let Date = columns.filter(v => v.valueType === 'Date')
                    if (Date.length > 0)
                        Date.forEach(item => {
                            // console.log(TimeFormatConversion(initial[item.dataIndex], item, 0))
                            initial[item.dataIndex] = TimeFormatConversion(initial[item.dataIndex], item, 0)
                        })
                    let ICON = columns.filter(v => v.valueType === 'ICON')
                    if (ICON.length > 0)
                        ICON.forEach(item =>
                            data[item.valueJudge] === '00000000-0000-0000-0000-000000000000' ? IconTrue() : IconFalse(),
                        )
                    let cascaderSelect = columns.filter(v => v.valueType === 'cascaderSelect')
                    if (cascaderSelect.length > 0) {
                        cascaderSelect.forEach(item => {
                            initial[item.dataIndex] = item.callbackData.map(key => data[key])
                            let option = item.defaultValue.map((key, index) => ({
                                label: initial[key],
                                value: initial[item.dataIndex][index],
                                id: index + 1,
                                parent: index,
                            }))
                            item.option = cloneTree(option)
                        })
                    }
                    form.setFieldsValue(initial)
                    setPageData(columns)
                } else setPageData(res.columns.filter(v => !v.hideInAdded))
                setAddAPI(res.added)
                setPutAPI(res.modify)
                setFalse()
            } else {
                message.success('字段列表获取失败!')
            }
        },
        [AddTo, IconFalse, IconTrue, data, form, setFalse],
    )
    // 处理提交数据
    const SubmitForProcessing = (res, val) => {
        if (AddTo) val[AddTo.key] = AddTo.uuid
        const columns = res.columns.filter(v => !v.hideInModify)
        // 判断数据类型
        // 时间类型
        let Date = columns.filter(v => v.valueType === 'Date')
        if (Date.length > 0)
            Date.forEach(item => {
                val[item.dataIndex] = TimeFormatConversion(val[item.dataIndex], item, 1)
            })
        // 附件类型
        let UpLoad = columns.filter(v => v.valueType === 'upload')
        if (UpLoad.length > 0) {
            UpLoad.forEach(item => {
                if (val[item.dataIndex] && typeof val[item.dataIndex] !== 'string') {
                    const [{ response }] = val[item.dataIndex]
                    if (response) val[item.dataIndex] = response.uuid
                    else {
                        let tipsTitle = ''
                        item.valueFile.forEach(key => (tipsTitle += UploadFileMapping[key]))
                        message.error(`上传信息无误!请传入 ${tipsTitle}`)
                        setFalse()
                        return false
                    }
                }
            })
        }
        let ICON = columns.filter(v => v.valueType === 'ICON')
        if (ICON.length > 0)
            ICON.forEach(item => {
                if (val[item.valueJudge] !== '00000000-0000-0000-0000-000000000000') val[item.dataIndex] = ''
            })

        let cascaderSelect = columns.filter(v => v.valueType === 'cascaderSelect')
        if (cascaderSelect.length > 0)
            cascaderSelect.forEach(item => {
                item.callbackData.forEach((key, index) => (val[key] = val[item.dataIndex][index]))
                delete val[item.dataIndex]
            })
        let automatic = columns.filter(v => v.valueType === 'automatic')
        if (automatic.length > 0) {
            automatic.forEach(item => {
                val[item.dataIndex] = `${item.addonBefore || ''}${val[item.dataIndex]}${item.addonAfter || ''}`
            })
        }
        SubmitFunction(res, val)
    }
    // 提交函数
    const SubmitFunction = (res, val) => {
        let RequestData = val
        let RequestPath = [val.uuid]
        if (type) {
            RequestData = { ...val, ...res.additional }
            RequestPath = [res.uuid]
        }
        if (!!data) ModifyFunction(RequestData, RequestPath)
        else AddedFunction(RequestData, RequestPath)
    }
    // 修改数据
    const ModifyFunction = (data, path) => {
        runAsync({ url: PutAPI, data, path })
            .then(() => callBack('success', '修改成功!'))
            .catch(() => callBack('error', '修改失败!'))
    }
    // 新增数据
    const AddedFunction = (data, path) => {
        runAsync({ url: AddAPI, data, path })
            .then(() => callBack('success', '新增成功!'))
            .catch(() => callBack('error', '新增失败!'))
    }
    // 提交结果
    const callBack = (state, text) => {
        console.log()
        message[state](text)
        if (state === 'success') {
            if (actionRef.current) actionRef.current?.reload()
            else {
                RefreshEvent.emit()
                if (PPPEvent) PPPEvent.emit()
            }
            setTimeout(() => Off(), 500)
        } else setFalse()
    }
    useEffect(() => {
        if (url) {
            // 一级菜单数据
            if (!type) MenuBoxList(url, 0, uuid).then(res => RenderingForProcessing(res))
            // 三级菜单数据
            else ThrModalList({ value: url, data: thrData }).then(res => RenderingForProcessing(res))
        }
    }, [RenderingForProcessing, thrData, type, url, uuid])

    return (
        <Form
            form={form}
            className="FormClass"
            onFinish={val => {
                setTrue()
                if (!type)
                    MenuBoxList(url).then(res => {
                        SubmitForProcessing(res, val)
                    })
                else
                    ThrModalList({ value: url, data: thrData }).then(res => {
                        SubmitForProcessing(res, val)
                    })
            }}
            onValuesChange={e => {
                // 判断菜单是否有icon
                const iconJudge = PageData.findIndex(v => v.dataIndex === 'icon')
                if (iconJudge !== -1 && PageData[iconJudge].valueJudge) {
                    const { valueJudge } = PageData[iconJudge]
                    if (e[valueJudge])
                        e[valueJudge] === '00000000-0000-0000-0000-000000000000' ? IconTrue() : IconFalse()
                }
            }}
            // onFinishFailed={(e) => console.log(e)}
            autoComplete="off"
            labelAlign="right"
            labelWrap
        >
            <Spin spinning={loading}>
                <FormItem form={form} PageData={PageData} MenuIconState={MenuIconState} />
                <div className="FormBtn">
                    <Button style={{ width: 300 }} type="primary" htmlType="submit">
                        提交
                    </Button>
                </div>
            </Spin>
        </Form>
    )
}

export const FormItem = ({ form, PageData, MenuIconState, Viewing }) => {
    const [EnclosureModalData, setEnclosureModalData] = useState()
    const [EnclosureModalState, { setTrue: EnclosureTrue, setFalse: EnclosureFalse }] = useBoolean(false)
    return (
        <>
            {PageData &&
                PageData.filter(Boolean).map((item, index) => {
                    const {
                        valueType,
                        valueEnum,
                        valueFile,
                        title,
                        dataIndex,
                        rules,
                        multiple,
                        judgeType,
                        judge,
                        fieldProps,
                        picker,
                        showTime,
                        fileUrl,
                        className,
                        Hierarchy,
                        cascaderData,
                        option,
                        disabled,
                        addonBefore,
                        addonAfter,
                        automatic,
                        montage,
                        montageList,
                        help,
                        helpUrl,
                        helpText,
                    } = item
                    switch (valueType) {
                        //  隐藏
                        case 'hidden':
                            const HiddenForm = () => {
                                return (
                                    <Form.Item
                                        className="FormHidden"
                                        label={title}
                                        name={dataIndex}
                                        rules={[{ required: rules, message: `必须填写${title}!` }]}
                                    >
                                        <Input />
                                    </Form.Item>
                                )
                            }
                            return <HiddenForm key={`FormItem${index}`} />
                        //  文本框
                        case 'input':
                            const InputForm = () => {
                                return (
                                    <Form.Item
                                        className={className || 'FormItem'}
                                        label={title}
                                        name={dataIndex}
                                        rules={[{ required: rules, message: `必须填写${title}!` }]}
                                    >
                                        <Input
                                            disabled={disabled}
                                            style={{ width: '100%' }}
                                            placeholder={`请输入${title}`}
                                        />
                                    </Form.Item>
                                )
                            }
                            if (judge) {
                                return (
                                    <Form.Item
                                        key={`SearchForm-FormItem-${index}`}
                                        noStyle
                                        shouldUpdate={(prevValues, currentValues) =>
                                            prevValues[judgeType] !== currentValues[judgeType]
                                        }
                                    >
                                        {({ getFieldValue }) =>
                                            getFieldValue(judgeType) === judge ? <InputForm /> : null
                                        }
                                    </Form.Item>
                                )
                            }
                            return <InputForm key={`FormItem${index}`} />
                        case 'automatic':
                            const AutomaticForm = () => {
                                return (
                                    <Form.Item
                                        className={'FormHidden'}
                                        label={title}
                                        name={dataIndex}
                                        rules={[{ required: rules, message: `必须填写${title}!` }]}
                                    >
                                        <Input
                                            disabled={true}
                                            style={{ width: '100%' }}
                                            placeholder={`请输入${title}`}
                                            addonBefore={addonBefore}
                                            addonAfter={addonAfter}
                                        />
                                    </Form.Item>
                                )
                            }
                            return <AutomaticForm key={`FormItem${index}`} />
                        //  数字框
                        case 'inputNumber':
                            const InputNumberForm = () => {
                                return (
                                    <Form.Item
                                        className={className || 'FormItem'}
                                        label={title}
                                        name={dataIndex}
                                        rules={[{ required: rules, message: `必须填写${title}!` }]}
                                    >
                                        <InputNumber style={{ width: `100%` }} />
                                    </Form.Item>
                                )
                            }
                            return <InputNumberForm key={`FormItem${index}`} />
                        //  多行文本
                        case 'textarea':
                            const TextAreaFrom = () => {
                                return (
                                    <Form.Item
                                        className="FormAll"
                                        label={title}
                                        name={dataIndex}
                                        rules={[{ required: rules, message: `必须填写${title}!` }]}
                                    >
                                        <TextArea />
                                    </Form.Item>
                                )
                            }
                            return <TextAreaFrom key={`FormItem${index}`} />
                        //  下拉框
                        case 'select':
                            const SelectForm = () => {
                                const [options, setOptions] = useState([])
                                useEffect(() => {
                                    if (
                                        form &&
                                        (form.getFieldValue(item.dataIndex) ||
                                            form.getFieldValue(item.dataIndex) === 0) &&
                                        typeof form.getFieldValue(item.dataIndex) === 'number'
                                    )
                                        form.setFieldsValue({
                                            [item.dataIndex]: form.getFieldValue(item.dataIndex).toString(),
                                        })
                                    let data
                                    if (valueEnum instanceof Array) data = valueEnum
                                    else
                                        data = Object.keys(valueEnum).map(key => ({
                                            label: valueEnum[key],
                                            value: key,
                                        }))
                                    const sortData = (x, y) => {
                                        if (x.label < y.label) return -1
                                        if (x.label > y.label) return 1
                                        return 0
                                    }
                                    setOptions(data.sort(sortData))
                                }, [])

                                const SelectChange = e => {
                                    if (montage) {
                                        console.log(montage)
                                        console.log(e)
                                        console.log(options)
                                        console.log(montageList)
                                    }
                                }

                                return (
                                    <Form.Item
                                        className={className || 'FormItem'}
                                        label={title}
                                        name={dataIndex}
                                        rules={[{ required: rules, message: `必须填写${title}!` }]}
                                    >
                                        <Select
                                            disabled={disabled}
                                            showSearch={true}
                                            placeholder={`请选择${title}`}
                                            mode={multiple ? 'multiple' : ''}
                                            filterOption={(input, option) =>
                                                (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
                                            }
                                            options={options}
                                            onChange={SelectChange}
                                        />
                                    </Form.Item>
                                )
                            }
                            if (judge) {
                                return (
                                    <Form.Item
                                        key={`SearchForm-FormItem-${index}`}
                                        noStyle
                                        shouldUpdate={(prevValues, currentValues) =>
                                            prevValues[judgeType] !== currentValues[judgeType]
                                        }
                                    >
                                        {({ getFieldValue }) =>
                                            getFieldValue(judgeType) === judge ? <SelectForm /> : null
                                        }
                                    </Form.Item>
                                )
                            }
                            return <SelectForm key={`FormItem${index}`} />
                        //  树形下拉框
                        case 'treeSelect':
                            const TreeSelectForm = () => {
                                return (
                                    <Form.Item
                                        className={className || 'FormItem'}
                                        label={title}
                                        name={dataIndex}
                                        rules={[{ required: rules, message: `必须选择${title}!` }]}
                                    >
                                        <TreeSelect
                                            showSearch
                                            treeLine
                                            fieldNames={fieldProps.fieldNames}
                                            style={{ width: '100%' }}
                                            dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
                                            placeholder={`请选择${title}`}
                                            treeDefaultExpandAll
                                            treeData={fieldProps.options}
                                        />
                                    </Form.Item>
                                )
                            }
                            return <TreeSelectForm key={`FormItem${index}`} />
                        //  图标
                        case 'ICON':
                            const ICONForm = () => {
                                const [IconSelect, setIconSelect] = useState(form.getFieldValue(dataIndex))
                                useEffect(() => form.setFieldsValue({ [dataIndex]: IconSelect }), [IconSelect])
                                return (
                                    <>
                                        {MenuIconState && (
                                            <Form.Item
                                                className="FormAll"
                                                label={title}
                                                name={dataIndex}
                                                rules={[{ required: rules, message: `必须选择${title}!` }]}
                                            >
                                                <div className="SelectIcon">
                                                    {Object.keys(ICON).map((item, index) => (
                                                        <div
                                                            key={`SelectIcon${index}`}
                                                            className={IconSelect === item ? 'active' : ''}
                                                            onClick={() => setIconSelect(item)}
                                                        >
                                                            {ICON[item]}
                                                        </div>
                                                    ))}
                                                </div>
                                            </Form.Item>
                                        )}
                                    </>
                                )
                            }
                            return <ICONForm key={`FormItem${index}`} />
                        // 日期选择
                        case 'Date':
                            const OnlyYearForm = () => {
                                const { runAsync: getDateData } = useRequest(Http, { manual: true })

                                const DateChange = e => {
                                    const year = e.year()
                                    const month = e.month() + 1
                                    const day = e.day()
                                    if (automatic) {
                                        switch (picker) {
                                            case 'year':
                                                form.setFieldsValue({ [automatic]: `${year}年` })
                                                break
                                            case 'month':
                                                form.setFieldsValue({ [automatic]: `${year}年${month}月` })
                                                break
                                            default:
                                                form.setFieldsValue({ [automatic]: `${year}年${month}月${day}日` })
                                                break
                                        }
                                    }
                                    if (help) {
                                        switch (help) {
                                            case 'bada':
                                                if (!form.getFieldValue('organizationUuid')) {
                                                    message.info('请先选择标段')
                                                    form.setFieldsValue({ [dataIndex]: '' })
                                                    return false
                                                }
                                                getDateData({
                                                    url: helpUrl,
                                                    data: {
                                                        year,
                                                        organizationUuid: form.getFieldValue('organizationUuid'),
                                                    },
                                                }).then(({ totalAmount, yearAmount }) => {
                                                    setHelpText(
                                                        <div className="Help">{`${year}年累计${helpText}：${yearAmount}万元、项目累计${helpText}：${totalAmount}万元`}</div>,
                                                    )
                                                })
                                                break
                                            default:
                                                break
                                        }
                                    }
                                }

                                useEffect(() => {
                                    if (help) {
                                        switch (help) {
                                            case 'bada':
                                                const year = form.getFieldValue(dataIndex)?.year()
                                                const organizationUuid = form.getFieldValue('organizationUuid')

                                                if (year && organizationUuid)
                                                    getDateData({
                                                        url: helpUrl,
                                                        data: { year, organizationUuid },
                                                    }).then(({ totalAmount, yearAmount }) => {
                                                        setHelpText(
                                                            <div className="Help">{`${year}年累计${helpText}：${yearAmount}万元、项目累计${helpText}：${totalAmount}万元`}</div>,
                                                        )
                                                    })
                                                break
                                            default:
                                                break
                                        }
                                    }
                                }, [getDateData])

                                const [helpContent, setHelpText] = useState()

                                return (
                                    <Form.Item
                                        className={className || 'FormItem'}
                                        label={title}
                                        name={dataIndex}
                                        rules={[{ required: rules, message: `必须选择${title}!` }]}
                                        help={helpContent}
                                    >
                                        <DatePicker
                                            onChange={DateChange}
                                            style={{ width: '100%' }}
                                            picker={picker}
                                            showTime={showTime}
                                        />
                                    </Form.Item>
                                )
                            }
                            return <OnlyYearForm key={`FormItem${index}`} />
                        // 上传
                        case 'upload':
                            const UploadForm = () => {
                                const [loading, { setTrue, setFalse }] = useBoolean(false)
                                const [imageUrl, setImageUrl] = useState('')
                                const [FileType, setFileType] = useState(0)
                                const normFile = e => {
                                    if (Array.isArray(e)) return e
                                    return e && e.fileList
                                }

                                useEffect(() => {
                                    if (form.getFieldValue(fileUrl)) {
                                        setImageUrl(form.getFieldValue(fileUrl))
                                        setTrue()
                                    }
                                }, [setTrue])

                                const beforeUpload = ({ name, size }) => {
                                    const isLt1G = size / 1024 / 1024 / 1024 < 1
                                    let fileTypeIdex = false
                                    if (!isLt1G) message.error('文件大小不得超过 1GB!')
                                    const fileType = name.split('.').at(-1).toLowerCase()
                                    UploadFileType.forEach((item, index) => {
                                        if (item.indexOf(fileType) !== -1) {
                                            fileTypeIdex = index
                                            setFileType(index)
                                        }
                                    })

                                    if (fileTypeIdex === false) {
                                        message.error('暂不支持上传该文件类型,请及时联系管理员!')
                                        return false
                                    }

                                    if (valueFile.indexOf(fileTypeIdex) === -1) {
                                        let tipsTxt = ''
                                        valueFile.forEach(item => (tipsTxt += ` ${UploadFileMapping[item]}`))
                                        message.error(`请上传 ${tipsTxt}`)
                                        return false
                                    }
                                    return isLt1G
                                }
                                const props = {
                                    name: 'file',
                                    action: API_LIST()[`posAttachment`],
                                    headers: { Authorization: `${sessionStorage.getItem('TOKEN')}` },
                                    maxCount: 1,
                                    defaultFileList: [],
                                    onChange(info) {
                                        if (info.file.status === 'done') {
                                            setTrue()
                                            setImageUrl(info.file.response.fileUrl)
                                            message.success(`${info.file.name} 上传成功`)
                                        } else if (info.file.status === 'error')
                                            message.error(`${info.file.name} 上传失败.`)
                                    },
                                    onPreview() {
                                        if (!form.getFieldValue(fileUrl)) {
                                            EnclosureTrue()
                                            setEnclosureModalData({ className: 'Admin', url: imageUrl })
                                        }
                                    },
                                    onRemove() {
                                        setFalse()
                                    },
                                    progress: {
                                        strokeColor: { '0%': '#108ee9', '100%': '#87d068' },
                                        strokeWidth: 3,
                                        format: percent => `${parseFloat(percent.toFixed(2))}%`,
                                    },
                                }

                                const defaultFileList = form.getFieldValue(dataIndex)
                                if (typeof defaultFileList === 'string')
                                    props.defaultFileList = [{ name: defaultFileList }]

                                return (
                                    <Form.Item
                                        name={dataIndex}
                                        label={title}
                                        className="RemarkForm"
                                        valuePropName="attachment"
                                        getValueFromEvent={normFile}
                                        rules={
                                            item.rulesRule
                                                ? item.rulesRule
                                                : [{ required: item.rules, message: `必须填写${item.title}!` }]
                                        }
                                    >
                                        <Upload
                                            className="UpLoadStyle"
                                            beforeUpload={beforeUpload}
                                            data={{ FileType }}
                                            {...props}
                                        >
                                            <Button
                                                className="uploadButton"
                                                disabled={loading}
                                                icon={<PlusOutlined style={{ fontSize: 25 }} />}
                                            />
                                        </Upload>
                                    </Form.Item>
                                )
                            }
                            return <UploadForm key={`FormItem${index}`} />

                        case 'cascaderSelect':
                            const CascaderForm = () => {
                                const { one, two, thr, fou, fiv } = cascaderData
                                const HierarchyMapping = { 1: one, 2: two, 3: thr, 4: fou, 5: fiv }
                                const { runAsync: getCascaderData } = useRequest(Http, { manual: true })
                                const [options, setOptions] = useState(option)

                                useEffect(() => {
                                    if (!option) {
                                        const { api, mapping } = one
                                        getCascaderData({ url: api }).then(({ list }) =>
                                            setOptions(
                                                list.map(item => ({
                                                    label: item[mapping.label],
                                                    value: item[mapping.value],
                                                    isLeaf: false,
                                                })),
                                            ),
                                        )
                                    }
                                }, [getCascaderData, one])

                                const loadData = e => {
                                    const targetOption = e[e.length - 1]
                                    targetOption.loading = true
                                    if (HierarchyMapping[e.length + 1]) {
                                        const { api, mapping, parameter, replace } = HierarchyMapping[e.length + 1]
                                        if (replace) {
                                            setTimeout(() => {
                                                targetOption.loading = false
                                                targetOption.children = replace
                                                setOptions([...options])
                                            }, 1000)
                                        } else {
                                            let params = {}
                                            parameter.forEach(
                                                (key, index) => (params = { ...params, [key]: e[index].value }),
                                            )
                                            getCascaderData({ url: api, data: params }).then(({ list }) => {
                                                targetOption.loading = false
                                                targetOption.children = list.map(item => ({
                                                    label: item[mapping.label],
                                                    value: item[mapping.value],
                                                    isLeaf: Number(Hierarchy) === Number(e.length + 1),
                                                }))
                                                setOptions([...options])
                                            })
                                        }
                                    }
                                }
                                return (
                                    <Form.Item
                                        className={className || 'FormItem'}
                                        label={title}
                                        name={dataIndex}
                                        rules={[{ required: rules, message: `必须选择${title}!` }]}
                                    >
                                        <Cascader changeOnSelect loadData={loadData} options={options} />
                                    </Form.Item>
                                )
                            }
                            return <CascaderForm key={`FormItem${index}`} />
                        // 其他自定义组件
                        case 'Bidirectional':
                            const BidirectionalFrom = () => {
                                const [BidirectionalTableName, setBidirectionalTableName] = useState()
                                const [BidirectionalFromOneData, setBidirectionalFromOneData] = useState()
                                const [BidirectionalFromTwoData, setBidirectionalFromTwoData] = useState()
                                const { runAsync: getCenterTypeUpdateGetCenterTypeinfo } = useRequest(Http, {
                                    manual: true,
                                })

                                const BidirectionalFromOneChange = e => {
                                    form.setFieldsValue({
                                        centerTypeName: BidirectionalFromOneData.find(v => v.value === e).label,
                                    })
                                }
                                const BidirectionalFromTwoChange = e => {
                                    form.setFieldsValue({
                                        typeName: BidirectionalFromTwoData.find(v => v.value === e).label,
                                    })
                                }

                                useEffect(() => {
                                    if (BidirectionalTableName) {
                                        getCenterTypeUpdateGetCenterTypeinfo({
                                            url: 'getCenterTypeUpdateGetCenterTypeinfo',
                                            data: { tablename: BidirectionalTableName },
                                        }).then(res => {
                                            const { centertype, pushtype } = res
                                            let centertypeData = JSON.parse(centertype).map(({ name, uuid }) => ({
                                                label: name,
                                                value: uuid,
                                            }))
                                            let pushtypeData = pushtype.map(({ name, uuid }) => ({
                                                label: name,
                                                value: uuid,
                                            }))
                                            setBidirectionalFromOneData(centertypeData)
                                            setBidirectionalFromTwoData(pushtypeData)
                                        })
                                    }
                                }, [BidirectionalTableName, getCenterTypeUpdateGetCenterTypeinfo])

                                return (
                                    <Form.Item
                                        noStyle
                                        shouldUpdate={(prevValues, currentValues) => {
                                            if (prevValues.tableName !== currentValues.tableName) {
                                                setBidirectionalTableName(currentValues.tableName)
                                                form.setFieldsValue({ centerTypeUuid: '', typeUuid: '' })
                                                return true
                                            }
                                        }}
                                    >
                                        {({ getFieldValue }) => {
                                            return (
                                                getFieldValue(judge) && (
                                                    <>
                                                        <Form.Item
                                                            className={className || 'FormItem'}
                                                            name="typeUuid"
                                                            label="子项目类型"
                                                            rules={[{ required: true }]}
                                                        >
                                                            <Select
                                                                options={BidirectionalFromTwoData}
                                                                onChange={BidirectionalFromTwoChange}
                                                            />
                                                        </Form.Item>
                                                        <Form.Item
                                                            className={className || 'FormItem'}
                                                            name="centerTypeUuid"
                                                            label="中心类型"
                                                            rules={[{ required: true }]}
                                                        >
                                                            <Select
                                                                options={BidirectionalFromOneData}
                                                                onChange={BidirectionalFromOneChange}
                                                            />
                                                        </Form.Item>
                                                        <Form.Item className="FormHidden" name="centerTypeName">
                                                            <Input />
                                                        </Form.Item>
                                                        <Form.Item className="FormHidden" name="typeName">
                                                            <Input />
                                                        </Form.Item>
                                                    </>
                                                )
                                            )
                                        }}
                                    </Form.Item>
                                )
                            }
                            return <BidirectionalFrom key={`FormItem${index}`} />

                        case 'selectMultiple':
                            const SelectMultipleFrom = () => {
                                const [SelectMultipleOptions, setSelectMultipleOptions] = useState([])

                                return (
                                    <Form.Item
                                        noStyle
                                        shouldUpdate={(prevValues, currentValues) => {
                                            if (prevValues[judge] !== currentValues[judge]) {
                                                setSelectMultipleOptions(
                                                    judgeType.find(v => v.trueUuid === currentValues[judge]).children,
                                                )
                                                form.setFieldsValue({ [dataIndex]: [] })
                                                return true
                                            }
                                        }}
                                    >
                                        {({ getFieldValue }) => {
                                            return (
                                                getFieldValue(judge) && (
                                                    <Form.Item
                                                        className={className || 'FormItem'}
                                                        name={dataIndex}
                                                        label={title}
                                                        rules={[{ required: true }]}
                                                    >
                                                        <Select
                                                            mode="multiple"
                                                            placeholder={`请选择${title}`}
                                                            options={SelectMultipleOptions}
                                                            fieldNames={{ label: 'tableName', value: 'trueUuid' }}
                                                        />
                                                    </Form.Item>
                                                )
                                            )
                                        }}
                                    </Form.Item>
                                )
                            }

                            return <SelectMultipleFrom key={`FormItem${index}`} />

                        case 'APSCenter':
                            const APSCenterForm = () => {
                                const [Center, setCenter] = useState(form.getFieldValue(dataIndex))
                                useEffect(() => form.setFieldsValue({ [dataIndex]: Center }), [Center])
                                return (
                                    <Form.Item
                                        name={dataIndex}
                                        label={title}
                                        className="FromItem"
                                        rules={
                                            item.rulesRule
                                                ? item.rulesRule
                                                : [{ required: item.rules, message: `必须保存${title}!` }]
                                        }
                                    >
                                        {Center ? (
                                            <div className="BtnList">
                                                <Button
                                                    onClick={() => {
                                                        const defaultViewer = {
                                                            center: new THREE.Vector3(
                                                                Center[0],
                                                                Center[1],
                                                                Center[2],
                                                            ).clone(),
                                                            fov: Center[3],
                                                            isOrtho: Center[4],
                                                            pivot: new THREE.Vector3(
                                                                Center[5],
                                                                Center[6],
                                                                Center[7],
                                                            ).clone(),
                                                            position: new THREE.Vector3(
                                                                Center[8],
                                                                Center[9],
                                                                Center[10],
                                                            ).clone(),
                                                            up: new THREE.Vector3(
                                                                Center[11],
                                                                Center[12],
                                                                Center[13],
                                                            ).clone(),
                                                            worldUp: new THREE.Vector3(
                                                                Center[14],
                                                                Center[15],
                                                                Center[16],
                                                            ).clone(),
                                                        }
                                                        Viewing.autocam.goToView(defaultViewer)
                                                    }}
                                                    style={{ marginRight: 15 }}
                                                >
                                                    归位
                                                </Button>
                                                <Button
                                                    danger
                                                    onClick={() => {
                                                        let arr = []
                                                        const { center, fov, isOrtho, pivot, position, up, worldUp } =
                                                            Viewing.autocam.getCurrentView()
                                                        // !!! 添加轴心点位置
                                                        arr = [
                                                            center.x,
                                                            center.y,
                                                            center.z,
                                                            fov,
                                                            isOrtho,
                                                            pivot.x,
                                                            pivot.y,
                                                            pivot.z,
                                                            position.x,
                                                            position.y,
                                                            position.z,
                                                            up.x,
                                                            up.y,
                                                            up.z,
                                                            worldUp.x,
                                                            worldUp.y,
                                                            worldUp.z,
                                                        ]
                                                        setCenter(arr)
                                                    }}
                                                >
                                                    更换
                                                </Button>
                                            </div>
                                        ) : (
                                            <Button
                                                block
                                                onClick={() => {
                                                    let arr = []
                                                    const { center, fov, isOrtho, pivot, position, up, worldUp } =
                                                        Viewing.autocam.getCurrentView()
                                                    arr = [
                                                        center.x,
                                                        center.y,
                                                        center.z,
                                                        fov,
                                                        isOrtho,
                                                        pivot.x,
                                                        pivot.y,
                                                        pivot.z,
                                                        position.x,
                                                        position.y,
                                                        position.z,
                                                        up.x,
                                                        up.y,
                                                        up.z,
                                                        worldUp.x,
                                                        worldUp.y,
                                                        worldUp.z,
                                                    ]
                                                    setCenter(arr)
                                                }}
                                            >
                                                保存视角
                                            </Button>
                                        )}
                                    </Form.Item>
                                )
                            }

                            return <APSCenterForm key={`FormItem${index}`} />

                        case 'APSAxis':
                            const APSAxisForm = () => {
                                return (
                                    <Form.Item
                                        label={title}
                                        className="fromItem"
                                        rules={
                                            item.rulesRule
                                                ? item.rulesRule
                                                : [{ required: item.rules, message: `必须保存${title}!` }]
                                        }
                                    >
                                        <Button
                                            block
                                            onClick={() => {
                                                let { x, y, z } = Viewing.navigation.getPivotPoint()
                                                const Center = form.getFieldValue('center')
                                                if (Center) {
                                                    Center[5] = x
                                                    Center[6] = y
                                                    Center[7] = z
                                                    form.setFieldsValue({ center: Center })
                                                    message.success('轴心设置成功,请保存!')
                                                } else {
                                                    message.info('请先保存视角!')
                                                }
                                            }}
                                        >
                                            定位轴心点
                                        </Button>
                                    </Form.Item>
                                )
                            }

                            return <APSAxisForm key={`FormItem${index}`} />

                        default:
                            const UnknownForm = () => {
                                return (
                                    <Form.Item
                                        className="FormItem"
                                        label={title}
                                        name={dataIndex}
                                        rules={[{ required: rules, message: `必须填写${title}!` }]}
                                    >
                                        <div>未知组件</div>
                                    </Form.Item>
                                )
                            }
                            return <UnknownForm key={`FormItem${index}`} />
                    }
                })}
            {EnclosureModalState && <SeeEnclosureModal data={EnclosureModalData} Off={EnclosureFalse} />}
        </>
    )
}
